package com.ninong.ker.common.auth;

import java.security.Key;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import com.alibaba.fastjson.JSONObject;
import com.ninong.ker.common.tools.RedisUtils;
import com.ninong.ker.common.user.OnlineUser;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

/**
 * 安全管理文件
 * @author cmd
 *
 */
@Component
public class SecurityAdmin implements InitializingBean {

	private final JwtProperties properties;
	private Key key;
	private RedisUtils redisUtils;
	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	public SecurityAdmin(JwtProperties properties,RedisUtils redisUtils) {
		this.properties = properties;
		this.redisUtils = redisUtils;
	}

	@Override
	public void afterPropertiesSet() {
		byte[] keyBytes = Decoders.BASE64.decode(properties.getSecret());
		this.key = Keys.hmacShaKeyFor(keyBytes);
	}

	/**
	 * 生成token
	 *
	 * @param login
	 * @return
	 */
	public String createToken(String login) {
		return Jwts.builder().setSubject(login)
				.signWith(key, SignatureAlgorithm.HS512)
				// 加入ID确保生成的 Token 都不一致
				.setId(UUID.randomUUID().toString()).compact();
	}

	/**
	 * 获取当前登录用户
	 * 
	 * @param token
	 * @return
	 */
	public OnlineUser currentUser(String token) {
		Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
		return JSONObject.parseObject(claims.getSubject(), OnlineUser.class);
	}
	
	/**
	 * 获取当前登录用户
	 * 
	 * @param token
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<String> getAuthorities(String token) {
		String login = redisUtils.get(properties.getOnline() + token).toString();
		JSONObject json = JSONObject.parseObject(login);
		return (List<String>) json.get("roles");
	}

	/**
	 * 校验token
	 * 
	 * @param authToken
	 * @return
	 */
	public boolean validateToken(String authToken) {
		Object token = redisTemplate.opsForValue().get(properties.getOnline() + authToken);
		if(!ObjectUtils.isEmpty(token)) {
			return true;			
		}
		return false;
	}

	/**
	 * 获取token
	 * 
	 * @param request
	 * @return
	 */
	public String getToken(ServerHttpRequest request) {
		final String requestHeader = request.getHeaders().getFirst(properties.getHeader());
		return requestHeader;
	}
	
	/**
	 * 获取token
	 * 
	 * @param request
	 * @return
	 */
	public String getToken(HttpServletRequest request) {
		final String requestHeader = request.getHeader(properties.getHeader());
		return requestHeader;
	}
	
	/**
	 * 是否开启接口校验
	 * @return
	 */
	public Boolean getAuth() {
		return properties.getSecurity();		
	}
	
	/**
	 * 获取缓存中的字典集合
	 * @return
	 */
	public Object getDics(String key) {
		return redisUtils.get(key);		
	}
}
